home *** CD-ROM | disk | FTP | other *** search
- ; ROUTINES FOR CHAPTER 4 - GRAPHICS - ELEMENTARY FUNCTIONS
- ;
- ; For 320 x 200 color graphics mode
- ;
- ;**********************************************************
- datas segment public
- ;
- public x0,y0,x1,y1,x2,y2
- public color
- ;
- ; public parameters
- x0 dw ?
- y0 dw ?
- x1 dw ?
- y1 dw ?
- x2 dw ?
- y2 dw ?
- color dw ?
- ;
- ; tables of color masks for filling boxes
- cbytes db 000h, 055h, 0AAh, 0FFh
- ;
- xtable dw 0FFC0h, 0FFF0h, 0FFFCh, 0FFFFh
- dw 03FC0h, 03FF0h, 03FFCh, 03FFFh
- dw 00FC0h, 00FF0h, 00FFCh, 00FFFh
- dw 003C0h, 003F0h, 003FCh, 003FFh
- ;
- ; table of color masks for plotting points
- ctable dw 0003Fh,0403Fh,0803Fh,0C03Fh
- dw 000CFh,010CFh,020CFh,030CFh
- dw 000F3h,004F3h,008F3h,00CF3h
- dw 000FCh,001FCh,002FCh,003FCh
- ;
- datas ends
- ;**********************************************************
- video segment at 0B800h
- video ends
- ;**********************************************************
- ex4prim segment
- ;
- public cls
- public setpt,xorpt,locate
- public setbox,xorbox
- ;
- assume cs:ex4prim,ds:datas,es:video
- ;
- ;----------------------- routine begins -------------------------------+
- ; ROUTINE TO CLEAR THE GRAPHICS SCREEN
- ;
- cls proc far;
- push cx ; save registers
- push ax
- ;
- ; set up the registers
- mov cx,2000h ; word count of whole screen
- mov ax,0 ; zero pattern for the screen
- mov di,ax ; set starting address
- cld ; go in forward direction
- ;
- ; clear the screen with a single string operation
- rep stosw ; this clears the screen
- ;
- pop ax ; restore registers
- pop cx
- ret
- cls endp
- ;----------------------- routine ends --------------------------------+
- ;----------------------- routine begins -------------------------------+
- ; ROUTINE TO PLOT A POINT ON MEDIUM RES COLOR SCREEN
- ;
- setpt proc far
- ;
- push bx ; save registers
- push si
- push ax
- ;
- ; multiply y-coord by bytes per row and adjust for even/odd lines
- mov ax,di ; get y-coord into low part
- mov ah,al ; and into high part
- and ax,01FEh ; mask off unwanted parts
- sal ax,1 ; times 4
- sal ax,1 ; times 8
- sal ax,1 ; times 16
- mov bx,ax ; goes into address
- and bh,7 ; without adjustment
- sal ax,1 ; times 32
- sal ax,1 ; times 64
- add bx,ax ; address gets y-coord times 80
- ;
- ; add x-coord to address
- mov ax,si ; get x-coordinate
- sar ax,1 ; divide
- sar ax,1 ; by 4
- add bx,ax ; here is the address
- ;
- ; compute the rotated mask and color
- and si,3 ; just pixel position into the index
- sal si,1 ; index times 2
- sal si,1 ; index times 4
- add si,dx ; 4*pixel position + color
- sal si,1 ; 8*pixel position + 2*color
- mov ax,ctable[si] ; look up rotated color and mask
- ;
- ; insert the color into the video byte
- and al,es:[bx] ; get old byte & remove old pixel
- or al,ah ; insert new color
- mov es:[bx],al ; put the byte back
- ;
- pop ax ; restore registers
- pop si
- pop bx
- ret
- ;
- setpt endp
- ;----------------------- routine ends --------------------------------+
- ;----------------------- routine begins ------------------------------+
- ; ROUTINE TO XOR A POINT ONTO MEDIUM RES COLOR SCREEN
- ;
- xorpt proc far
- ;
- push bx ; save registers
- push si
- push ax
- ;
- ; multiply y-coord by bytes per row and adjust for even/odd lines
- mov ax,di ; get y-coord into low part
- mov ah,al ; and into high part
- and ax,01FEh ; mask off unwanted parts
- sal ax,1 ; times 4
- sal ax,1 ; times 8
- sal ax,1 ; times 16
- mov bx,ax ; goes into address
- and bh,7 ; without adjustment
- sal ax,1 ; times 32
- sal ax,1 ; times 64
- add bx,ax ; address gets y-coord times 80
- ;
- ; add x-coord to address
- mov ax,si ; get x-coordinate
- sar ax,1 ; divide
- sar ax,1 ; by 4
- add bx,ax ; here is the address
- ;
- ; compute the mask for color and use it
- and si,3 ; just the bit count into the index
- sal si,1 ; index times 2
- sal si,1 ; index times 4
- add si,dx ; 4*pixel position + color
- sal si,1 ; 8*pixel position + 2*color
- mov ax,ctable[si] ; look up the masks
- xor es:[bx],ah ; xor the byte with the color
- ;
- pop ax ; restore registers
- pop si
- pop bx
- ret
- ;
- xorpt endp
- ;----------------------- routine ends --------------------------------+
- ;----------------------- routine begins ------------------------------+
- ; ROUTINE TO RETURN COLOR OF A POINT ON MEDIUM RES COLOR SCREEN
- ;
- locate proc far
- ;
- push bx ; save registers
- push cx
- ;
- ; multiply y-coord by bytes per row and adjust for even/odd lines
- mov ax,di ; get y-coord into low part
- mov ah,al ; and into high part
- and ax,01FEh ; mask off unwanted parts
- sal ax,1 ; times 4
- sal ax,1 ; times 8
- sal ax,1 ; times 16
- mov bx,ax ; goes into address
- and bh,7 ; without adjustment
- sal ax,1 ; times 32
- sal ax,1 ; times 64
- add bx,ax ; address gets times 64 + times 16
- ;
- ; add x-coord to address
- mov ax,si ; get x-coordinate
- sar ax,1 ; divide
- sar ax,1 ; by 4
- add bx,ax ; here is the address
- ;
- ; compute the position of the pixel in the byte
- mov cx,si ; use x-coordinate to determine count
- and cx,3 ; just the bit count
- inc cx ; plus one
- sal cx,1 ; 2 bits per pixel
- ;
- ; get the byte and rotate into place
- mov al,es:[bx] ; get old byte
- rol al,cl ; rotate left this many times
- and ax,3 ; just the pixel color
- ;
- pop cx ; restore the registers
- pop bx
- ret
- ;
- locate endp
- ;----------------------- routine ends --------------------------------+
- ;----------------------- routine begins ------------------------------+
- ; ROUTINE TO FILL A RECTANGULAR BOX
- ;
- setbox proc far
- ;
- push si ; save registers
- push di
- push dx
- push bx
- push cx
- push ax
- ;
- ; determine byte position for start
- ;
- ; get y contribution
- mov ax,y1 ; get starting y-coordinate
- mov ah,al ; replicate for odd/even bank
- and ax,1FEh ; just one bit gets moved
- sal ax,1 ; times 4
- sal ax,1 ; times 8
- sal ax,1 ; times 16
- mov di,ax ; address gets 16 times y-coordinate
- and di,7FFh ; not the odd/even bit
- sal ax,1 ; times 32
- sal ax,1 ; times 64
- add di,ax ; address gets 80 times y-coordinate
- ;
- ; add in x contribution
- mov ax,x1 ; get x-coordinate
- sar ax,1 ; divide
- sar ax,1 ; by 4
- add di,ax ; beginning offset
- ;
- ; count for outer loop
- mov cx,y2 ; ending y-coordinate
- sub cx,y1 ; minus starting y-coordinate
- inc cx ; plus one
- ;
- ; count for inner loop
- mov si,x2 ; ending x-coordinate
- sar si,1 ; divide
- sar si,1 ; by 4
- mov ax,x1 ; starting x-coordinate
- sar ax,1 ; divide
- sar ax,1 ; by 4
- sub si,ax ; take the difference
- ;
- ; get the color
- mov bx,color ; get the color
- and bx,3 ; just between 0 and 3
- mov dl,cbytes[bx] ; look up color pattern
- ;
- ; determine mask for start and ending bytes
- mov bx,x1 ; starting byte
- and bx,3 ; just the pixel position
- sal bx,1 ; times 2
- sal bx,1 ; times 4
- mov ax,x2 ; ending byte
- and ax,3 ; just the pixel position
- add bx,ax ; 4*starting+ending
- sal bx,1 ; 8*starting+2*ending
- mov bx,xtable[bx] ; look up the masks
- ;
- ; set up masked color bytes
- mov dh,dl ; color for left bytes
- mov ah,dl ; color for middle bytes
- and dx,bx ; mask left and right color bytes
- ;
- cld ; forward
- ;
- sboxloop:
- push cx ; save count of outer loop
- push di ; save initial byte position
- ;
- mov cx,si ; count for inner loop
- ;
- ; check for only one byte
- mov al,bh ; get the mask
- jcxz sboxloop2 ; if ending byte coincides
- ;
- ; color leftmost byte of the scan line
- not al ; reverse the mask for clearing
- and al,es:[di] ; get byte from memory and clear pixels
- or al,dh ; put color in place
- stosb ; put byte in place
- ;
- ; check for just two bytes
- dec cx ; count the byte
- jcxz sboxloop1 ; done?
- ;
- ; color middle bytes of the scan line
- mov al,ah ; color for middle bytes
- rep stosb ; put middle bytes in place
- ;
- ; handle rightmost byte of the scan line
- ;
- ; come here if two or more bytes
- sboxloop1:
- mov al,0FFh ; set full mask
- ;
- ; in any case come here to adjust the masks
- sboxloop2:
- and al,bl ; bring in right part of mask
- and dl,al ; clear left part of color if needed
- ;
- ; color the byte
- not al ; reverse the mask for clearing
- and al,es:[di] ; get byte from memory and clear pixels
- or al,dl ; put pixels in the byte
- stosb ; put byte back into video RAM
- ;
- ; compute next scan line
- pop di ; retore address of left side of box
- test di,2000h ; odd or even line?
- jz sboxloop3 ; skip if even
- add di,80 ; add 80 bytes per line
- sboxloop3:
- xor di,2000h ; changes banks in any case
- pop cx ; restore count for outer loop
- loop sboxloop ; next scan line
- ;
- pop ax ; restore registers
- pop cx
- pop bx
- pop dx
- pop di
- pop si
- ret
- ;
- setbox endp
- ;----------------------- routine ends --------------------------------+
- ;----------------------- routine begins ------------------------------+
- ; ROUTINE TO XOR A RECTANGULAR BOX
- ;
- xorbox proc far
- ;
- push si ; save registers
- push di
- push dx
- push bx
- push cx
- push ax
- ;
- ; determine byte position for start
- ;
- ; get y contribution
- mov ax,y1 ; get starting y-coordinate
- mov ah,al ; replicate for odd/even bank
- and ax,1FEh ; just one bit gets moved
- sal ax,1 ; times 4
- sal ax,1 ; times 8
- sal ax,1 ; times 16
- mov di,ax ; address gets 16 times y-coordinate
- and di,7FFh ; not the odd/even bit
- sal ax,1 ; times 32
- sal ax,1 ; times 64
- add di,ax ; address gets 80 times y-coordinate
- ;
- ; add in x contribution
- mov ax,x1 ; get x-coordinate
- sar ax,1 ; divide
- sar ax,1 ; by 4
- add di,ax ; beginning offset
- ;
- ; count for outer loop
- mov cx,y2 ; ending y-coordinate
- sub cx,y1 ; minus starting y-coordinate
- inc cx ; plus one
- ;
- ; count for inner loop
- mov si,x2 ; ending x-coordinate
- sar si,1 ; divide
- sar si,1 ; by 4
- mov ax,x1 ; starting x-coordinate
- sar ax,1 ; divide
- sar ax,1 ; by 4
- sub si,ax ; take the difference
- ;
- ; get the color
- mov bx,color ; get the color
- and bx,3 ; just between 0 and 3
- mov dl,cbytes[bx] ; look up color pattern
- ;
- ; determine mask for start and ending bytes
- mov bx,x1 ; starting byte
- and bx,3 ; just the pixel position
- sal bx,1 ; times 2
- sal bx,1 ; times 4
- mov ax,x2 ; ending byte
- and ax,3 ; just the pixel position
- add bx,ax ; 4*starting+ending
- sal bx,1 ; 8*starting+2*ending
- mov bx,xtable[bx] ; look up the masks
- ;
- ; set up masked color bytes
- mov dh,dl ; color for left bytes
- mov ah,dl ; color for middle bytes
- and dx,bx ; mask left and right color bytes
- ;
- cld ; forward direction
- ;
- xboxloop:
- push cx ; save count for outer loop
- push di ; save address of leftmost byte
- ;
- mov cx,si ; count for inner loop
- ;
- ; check if only one byte in a scan line
- mov al,bh ; get the mask
- jcxz xboxloop3 ; ending byte coincides
- ;
- ; xor the leftmost byte
- xor es:[di],dh ; xor color into memory
- inc di ; next byte
- dec cx ; count it
- jcxz xboxloop2 ; done?
- ;
- ; xor the middle bytes
- xboxloop1:
- xor es:[di],ah ; xor color byte into memory
- inc di ; next byte
- loop xboxloop1 ; loop to get all the middle
- ;
- ; handle the rightmost byte
- ;
- ; come here if two or more bytes
- xboxloop2:
- mov al,0FFh ; set full mask
- ;
- ; in any case come here to adjust
- xboxloop3:
- and al,bl ; bring in right part
- and dl,al ; mask the color if needed
- ;
- ; xor the rightmost byte
- xor es:[di],dl ; xor byte into memory
- inc di ; next byte
- ;
- pop di ; restore the leftmost address
- test di,2000h ; odd or even scan line?
- jz xboxloop4 ; skip if even
- add di,80 ; add 80 if odd
- xboxloop4:
- xor di,2000h ; switch banks in any case
- pop cx ; restore count of outer loop
- loop xboxloop ; loop for next scan line
- ;
- pop ax ; restore registers
- pop cx
- pop bx
- pop dx
- pop di
- pop si
- ret
- ;
- xorbox endp
- ;----------------------- routine ends --------------------------------+
- ex4prim ends ; end of code segment
- ;
- end